home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / python / maclibnx.lha / set_open_hook.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-14  |  3.3 KB  |  132 lines

  1. /* A procedure to install a hook in the MPW C 'open' library function.
  2.    This is useful because you may want to create files automatically
  3.    with type 'TEXT' without having to change all the 'open' or 'fopen'
  4.    calls in a large C program you are trying to port.  A standard hook
  5.    procedure for this purpose is also provided.   
  6.  
  7.    Call:
  8.        set_open_hook(proc);
  9.    This installs the hook proc, or restores the default situation if
  10.    proc is NULL.
  11.    The hook procedure will be called immediately *after* a successful
  12.    open call, with the following parameters:
  13.        proc(filename, oflag, fd)
  14.         char *filename;        The file name
  15.         int oflag;        Mode passed to open
  16.         int fd;            Return value from open
  17.  
  18.    Note: this only works when the program is linked as an application
  19.    (type APPL); for tools (type MPST) the device switch is located
  20.    in the Shell's memory.
  21.    
  22.    Careful! this information was gathered by disassembling parts
  23.    of the library.
  24.    There are no guarantees that the same code will work in future
  25.    versions of MPW.  It has been tested with versions 1.0B2 through 2.01.
  26.    
  27.    Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
  28. */
  29.  
  30. #include "macdefs.h"
  31. #include <fcntl.h>
  32. #include "intercept.h"
  33.  
  34. #define ERRFLAG 0x40000000
  35.  
  36. static ProcPtr open_hook;
  37.  
  38. /* The hook for faccess, installed in the device switch.
  39.    This will be called with cmd == F_OPEN from 'open',
  40.    but also from 'faccess', with other values for cmd.
  41.    The open_hook is only called if cmd == F_OPEN.
  42.    It is not necessary to check whether open_hook is NULL,
  43.    since we are only installed after open_hook is set non-NULL. */
  44.  
  45. static long
  46. my_faccess(file, cmd, arg)
  47.     char *file;
  48.     int cmd;
  49.     short *arg;
  50. {
  51.     long res= _fsFAccess(file, cmd, arg);
  52.     
  53.     if (cmd == F_OPEN && !(res&ERRFLAG)) {
  54.         (void) (*open_hook)(file, *arg, (int)res);
  55.     }
  56.     return res;
  57. }
  58.  
  59. /* Standard open hook, to set type and creator of created files.
  60.    It will not change existing non-zero type or creator fields.
  61.    It returns an error code even though this is ignored by the
  62.    calling routine; you might want to call it yourself in a more
  63.    fancyful hook, and test the error code.
  64.    This routine can be customized by changing 'std_type' or
  65.    'std_creator'. */
  66.  
  67. OSType std_type=    'TEXT';
  68. OSType std_creator=    'MPS ';
  69.  
  70. int
  71. std_open_hook(file, mode, fd)
  72.     char *file;
  73.     int mode;
  74.     int fd;
  75. {
  76.     FInfo info;
  77.     int err= noErr;
  78.     
  79.     switch (mode & 03) {
  80.     
  81.     case O_RDWR:
  82.     case O_WRONLY:
  83.         err= GetFInfo(file, 0, &info);
  84.         if (err != noErr)
  85.             return err;
  86.         if (info.fdType == 0) {
  87.             info.fdType= std_type;
  88.             ++err; /* Use 'err' as a flag to call SetFInfo */
  89.         }
  90.         if (info.fdCreator == 0) {
  91.             info.fdCreator= std_creator;
  92.             ++err;
  93.         }
  94.         if (err != noErr)
  95.             err= SetFInfo(file, 0, &info);
  96.     
  97.     }
  98.     return err;
  99. }
  100.  
  101. /* The procedure to install the hook.
  102.    Note: this assumes nobody else is also installing hooks
  103.    for faccess, otherwise we would have to save and restore
  104.    the old function, instead of blindly assuming _fsFAccess. */
  105.  
  106. set_open_hook(hook)
  107.     ProcPtr hook;
  108. {
  109.     if (hook == NULL)
  110.         _StdDevs[DEV_FSYS].dev_faccess= _fsFAccess;
  111.     else {
  112.         open_hook= hook;
  113.         _StdDevs[DEV_FSYS].dev_faccess= my_faccess;
  114.     }
  115. }
  116.  
  117. /* A trivial test program will be included if you #define MAIN: */
  118.  
  119. #ifdef MAIN
  120.  
  121. #include <stdio.h>
  122.  
  123. extern int std_open_hook();
  124.  
  125. main()
  126. {
  127.     set_open_hook(std_open_hook);
  128.     fclose(fopen("ABC", "a"));
  129. }
  130.  
  131. #endif
  132.